using NUnit.Framework;

namespace CodeContrib.Tests
{
	public class StringExtensionsTests
	{
		[Test]
		public void CharsToUpper_With_Invalid_Indexes()
		{
			// Arrange
			const string expected = "sentence";

			const string value = "sentence";

			// Act
			var actual = value.CharsToUpper(-1, value.Length);

			// Assert
			Assert.AreEqual(expected, actual);
		}

		[Test]
		public void CharsToUpper_With_Valid_Indexes()
		{
			// Arrange
			const string expected = "SeNtEnCe";

			const string value = "sentence";

			// Act
			var actual = value.CharsToUpper(0, 2, 4, 6);

			// Assert
			Assert.AreEqual(expected, actual);
		}

		[Test]
		public void FormatParagraph_With_1_Sentence()
		{
			// Arrange
			const string expected = "Sentence 1.";

			const string paragraph = "sentence 1";

			// Act
			var actual = paragraph.FormatParagraph();

			// Assert
			Assert.AreEqual(expected, actual);
		}

		[Test]
		public void FormatParagraph_With_2_Sentences()
		{
			// Arrange
			const string expected = "Sentence 1. Sentence 2. Sentence 3.";

			const string paragraph = "sentence 1. sentence 2. sentence 3";

			// Act
			var actual = paragraph.FormatParagraph();

			// Assert
			Assert.AreEqual(expected, actual);
		}

		[Test]
		public void FormatParagraph_With_3_Sentences()
		{
			// Arrange
			const string expected = "Sentence 1. Sentence 2. Sentence 3.";

			const string paragraph = "sentence 1. sentence 2. sentence 3.";

			// Act
			var actual = paragraph.FormatParagraph();

			// Assert
			Assert.AreEqual(expected, actual);
		}

		[Test]
		public void FormatParagraph_With_EmptyString_ShouldReturn_EmptyString()
		{
			// Arrange
			const string expected = "";

			const string value = "";

			// Act
			var actual = value.FormatParagraph();

			// Assert
			Assert.AreEqual(expected, actual);
		}

		[Test]
		public void HtmlSubstring_With_1_Container_And_2_Paragraphs_ShouldReturn_Substring_And()
		{
			// Arrange
			const string html = "<div><p>Paragraph 1.</p><p>Paragraph 2.</p></div>";

			const string expected = "<div><p>Paragraph 1.</p><p>Par...</p></div>";

			// Act
			var actual = html.HtmlSubstring(15);

			// Assert
			Assert.AreEqual(expected, actual);
		}

		[Test]
		public void SplitSql_With_1_SqlStatement_ShouldReturn_1_SqlStatement()
		{
			// Arrange
			var expected = new[]
				               {
					               "SQL statement;"
				               };

			const string sql = "SQL statement";

			// Act
			var actual = sql.SplitSql();

			// Assert
			Assert.AreEqual(expected.Length, actual.Length);

			for (var sentenceIndex = 0; sentenceIndex < expected.Length; sentenceIndex++)
			{
				Assert.AreEqual(expected[sentenceIndex], actual[sentenceIndex]);
			}
		}

		[Test]
		public void SplitSql_With_2_SqlStatements_ShouldReturn_2_SqlStatements()
		{
			// Arrange
			var expected = new[]
				               {
					               "SQL statement 1;", "SQL statement 2;"
				               };

			const string sql = "SQL statement 1; SQL statement 2";

			// Act
			var actual = sql.SplitSql();

			// Assert
			Assert.AreEqual(expected.Length, actual.Length);

			for (var sentenceIndex = 0; sentenceIndex < expected.Length; sentenceIndex++)
			{
				Assert.AreEqual(expected[sentenceIndex], actual[sentenceIndex]);
			}
		}

		[Test]
		public void SplitSql_With_3_SqlStatements_And_SingleQuotes_ShouldReturn_3_SqlStatements()
		{
			// Arrange
			var expected = new[]
				               {
					               "SQL statement 1;", "'SQL statement 2;';", "SQL 'statement;' 3;"
				               };

			const string sql = "SQL statement 1; 'SQL statement 2;'; SQL 'statement;' 3";

			// Act
			var actual = sql.SplitSql();

			// Assert
			Assert.AreEqual(expected.Length, actual.Length, "sql={0}", sql);

			for (var sentenceIndex = 0; sentenceIndex < expected.Length; sentenceIndex++)
			{
				Assert.AreEqual(expected[sentenceIndex], actual[sentenceIndex], "sql={0} expected={1} actual={2}", sql, expected[sentenceIndex], actual[sentenceIndex]);
			}
		}

		[Test]
		public void Split_And_Trim_With_3_Sentences_And_Dot_Separator_ShouldReturn_3_Sentences()
		{
			// Arrange
			var expected = new[]
				               {
					               "sentence 1", "sentence 2", "sentence 3"
				               };

			const string paragraph = "sentence 1. sentence 2. sentence 3";

			// Act
			var actual = paragraph.Split(".", true);

			// Assert
			Assert.AreEqual(expected.Length, actual.Length);

			for (var sentenceIndex = 0; sentenceIndex < expected.Length; sentenceIndex++)
			{
				Assert.AreEqual(expected[sentenceIndex], actual[sentenceIndex]);
			}
		}
	}
}